package com.jokins.admin.ios.user.action;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jokins.admin.ios.user.actioncontext.BookUserUserLoginDoc;
import com.jokins.admin.ios.user.mapper.BookUserLoginRecordMapper;
import com.jokins.admin.ios.user.mapper.BookUserMapper;
import com.jokins.admin.ios.user.mapper.BookUserSignInMapper;
import com.jokins.admin.ios.user.param.BookUserUserLoginParam;
import com.jokins.admin.ios.user.vo.BookUserUserLoginVo;
import com.jokins.admin.vue.user.utils.SysUserStatus;
import com.jokins.common.actions.action.ActionContext;
import com.jokins.common.actions.action.BaseAction;
import com.jokins.common.actions.exception.BusinessException;
import com.jokins.common.constant.AccountEnum;
import com.jokins.common.constant.LevelValueEnum;
import com.jokins.common.entry.ios.login.BookUserLoginRecord;
import com.jokins.common.entry.ios.user.BookUser;
import com.jokins.common.entry.ios.user.BookUserSignIn;
import com.jokins.common.util.BusinessCode;
import com.jokins.common.util.BusinessProjectLabel;
import com.jokins.common.util.SqlTypeConverter;
import com.jokins.common.util.date.DateFormatter;
import com.jokins.common.util.ip.IpLocationQuery;
import com.jokins.common.util.passwore.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.Date;

/**
 * 〈〉<br>
 *
 * @author Mr.Wang
 * @create 2025/2/5
 */
@Slf4j
@Component
public class BookUserUserLoginDocAction extends BaseAction<BookUserUserLoginDoc> {

    @Autowired
    private BookUserMapper bookUserMapper;

    @Autowired
    private BookUserLoginRecordMapper bookUserLoginRecordMapper;

    @Autowired
    private BookUserSignInMapper bookUserSignInMapper;

    @Override
    protected void process(BookUserUserLoginDoc actionContext) throws BusinessException {
        BookUserUserLoginParam param = actionContext.getParam();
        BookUserUserLoginVo bookUserUserLoginVo = new BookUserUserLoginVo();
        try {
            LambdaQueryWrapper<BookUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(BookUser::getAccount, param.getAccount())
                    .or()
                    .eq(BookUser::getEasyAccount, param.getAccount())
                    .or()
                    .eq(BookUser::getCustomizeAccount, param.getAccount())
                    .or()
                    .eq(BookUser::getEmail, param.getAccount())
                    .or()
                    .eq(BookUser::getPhone, param.getAccount());
            BookUser bookUser = bookUserMapper.selectOne(lambdaQueryWrapper);
            if (bookUser == null) {
                log.info("project:{},用户不存在", BusinessProjectLabel.IOS);
                throw new BusinessException("用户不存在", BusinessCode.PARAM_ERROR);
            }
            if (bookUser.getStatus() == SysUserStatus.PENDING_APPROVAL.getValue()) {
                log.info("project:{},用户被禁用", BusinessProjectLabel.IOS);
                throw new BusinessException("用户被禁用", BusinessCode.LOGIN_ERROR);
            }
            // 校验密码
            boolean isCipherTextValid = AESUtil.verifyCipherText(bookUser.getEncryptPassword(), param.getPassword(), bookUser.getSalt(), bookUser.getIv());
            if (!isCipherTextValid) {
                log.info("project:{},密码错误", BusinessProjectLabel.IOS);
                throw new BusinessException("密码错误", BusinessCode.PARAM_ERROR);
            } else {
                IpLocationQuery query = new IpLocationQuery();
                String location = query.getAddressByIP(param.getLastLoginIp());
                Timestamp logTime = new Timestamp(System.currentTimeMillis());
                LambdaUpdateWrapper<BookUser> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.eq(BookUser::getAccount, param.getAccount())
                        .or()
                        .eq(BookUser::getEasyAccount, param.getAccount())
                        .or()
                        .eq(BookUser::getCustomizeAccount, param.getAccount())
                        .or()
                        .eq(BookUser::getEmail, param.getAccount())
                        .or()
                        .eq(BookUser::getPhone, param.getAccount());
                lambdaUpdateWrapper.set(BookUser::getLoginCount, bookUser.getLoginCount() + 1);
                lambdaUpdateWrapper.set(BookUser::getLastLoginIp, param.getLastLoginIp());
                lambdaUpdateWrapper.set(BookUser::getLastLoginDeviceModel, param.getLastLoginDeviceModel());
                lambdaUpdateWrapper.set(BookUser::getLastLoginDeviceName, param.getLastLoginDeviceName());
                lambdaUpdateWrapper.set(BookUser::getLastLoginDeviceSystem, param.getLastLoginDeviceSystem());
                lambdaUpdateWrapper.set(BookUser::getLastLoginDeviceSystemVersion, param.getLastLoginDeviceSystemVersion());
                lambdaUpdateWrapper.set(BookUser::getLastLoginLocation, location);
                lambdaUpdateWrapper.set(BookUser::getLastLoginTime, logTime);
                bookUserMapper.update(null, lambdaUpdateWrapper);
                BookUserLoginRecord bookUserLoginRecord = new BookUserLoginRecord();
                bookUserLoginRecord.setUserId(bookUser.getId());
                bookUserLoginRecord.setLoginTime(logTime);
                bookUserLoginRecord.setLoginLocation(location);
                bookUserLoginRecord.setLoginIp(param.getLastLoginIp());
                bookUserLoginRecord.setLoginDeviceName(param.getLastLoginDeviceName());
                bookUserLoginRecord.setLoginDeviceModel(param.getLastLoginDeviceModel());
                bookUserLoginRecord.setLoginDeviceSystem(param.getLastLoginDeviceSystem());
                bookUserLoginRecord.setLoginDeviceSystemVersion(param.getLastLoginDeviceSystemVersion());
                bookUserLoginRecordMapper.insert(bookUserLoginRecord);
                SqlTypeConverter.convertEntity(bookUser, bookUserUserLoginVo, DateFormatter.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS);
                bookUserLoginRecord.setLoginTime(logTime);
                bookUserUserLoginVo.setLastLoginLocation(location);
                bookUserUserLoginVo.setLastLoginIp(param.getLastLoginIp());
                bookUserUserLoginVo.setLastLoginDeviceName(param.getLastLoginDeviceName());
                bookUserUserLoginVo.setLastLoginDeviceModel(param.getLastLoginDeviceModel());
                bookUserUserLoginVo.setLastLoginDeviceSystem(param.getLastLoginDeviceSystem());
                bookUserUserLoginVo.setLastLoginDeviceSystemVersion(param.getLastLoginDeviceSystemVersion());
                Integer levelValueEnd= LevelValueEnum.getByLevel(bookUserUserLoginVo.getLevel()).getLevelValueEnd();
                bookUserUserLoginVo.setLevelValueEnd(levelValueEnd);
                String accountType = AccountEnum.getChineseNameByEnglish(bookUser.getAccountType()).orElse("未知会员类型");
                bookUserUserLoginVo.setAccountType(accountType);
                LambdaQueryWrapper<BookUserSignIn> queryWrapper=new LambdaQueryWrapper<>();
                queryWrapper.eq(BookUserSignIn::getUserId,bookUser.getId())
                        .orderByDesc(BookUserSignIn::getCreatedTime)
                        .last("limit  1");
                BookUserSignIn lastSignIn = bookUserSignInMapper.selectOne(queryWrapper);
                if(lastSignIn!=null){
                    bookUserUserLoginVo.setSignInDate(lastSignIn.getSignInDate());
                    bookUserUserLoginVo.setExperience(lastSignIn.getExperience());
                    bookUserUserLoginVo.setTotalExperience(lastSignIn.getTotalExperience());
                }else{
                    bookUserUserLoginVo.setSignInDate(new Date());
                    bookUserUserLoginVo.setExperience(70);
                    bookUserUserLoginVo.setTotalExperience(0);
                }
                log.info("project:{},密码正确！用户:{},登录成功！信息刷新:{}", BusinessProjectLabel.IOS, bookUser.getAccount(), JSON.toJSONString(param));
                actionContext.setResult(ActionContext.RESULT_DOC_KEY, bookUserUserLoginVo);
            }
        } catch (Exception e) {
            log.error("project:{},复制属性失败:{}", BusinessProjectLabel.IOS, e);
            throw new BusinessException("系统错误", BusinessCode.SYSTEM_ERROR);
        }
    }
}